using System;
using System.Collections.Generic;
using System.Text;

namespace Survive.Library
{
    public class ModelBuilder
    {
        Model model;

        public IModel BuildDefaultModel()
        {
            Reset();

            // Add default spaces
            AddDefaultSpaces();

            return Model;
        }

        public IModel Build()
        {
            return Model;
        }

        public SpaceBuilder AddSpace(int spaceId)
        {
            return new SpaceBuilder(Model, Model.AddOrGetSpace(spaceId));
        }

        public void Reset()
        {
            model = null;
        }

        Model Model
        {
            get { if (model == null) model = new Model(); return model; }
        }

        void AddDefaultSpaces()
        {
            for (int row = 1; row <= 13; row++)
            {
                int offset = row % 2;

                for (int col = 1; col <= 12 - offset; col++)
                {
                    int spaceId = row * 100 + col;

                    // Check to see if this is ignored space
                    if (IsSkippedSpace(spaceId))
                        continue;

                    // Add space
                    SpaceBuilder space = AddSpace(spaceId);

                    // Add adjacencies
                    if (col > 1 && row > 1) AddAdjacentSpace(space, (row - 1) * 100 + col - 1 + offset); // Previous row #1
                    if (col < 12 - offset && row > 1) AddAdjacentSpace(space, (row - 1) * 100 + col + offset); // Previous row #2
                    if (col > 1) AddAdjacentSpace(space, spaceId - 1); // Current row #1
                    if (col < 12 - offset) AddAdjacentSpace(space, spaceId + 1); // Current row #2
                    if (col > 1 && row < 13) AddAdjacentSpace(space, (row + 1) * 100 + col - 1 + offset); // Next row #1
                    if (col < 12 - offset && row < 13) AddAdjacentSpace(space, (row + 1) * 100 + col + offset); // Next row #2
                }
            }
        }

        static readonly int[] skippedSpaces = new int[] { 101, 102, 110, 111, 201, 212, 401, 412, 1001, 1012, 1201, 1212, 1301, 1302, 1310, 1311 };

        bool IsSkippedSpace(int spaceId)
        {
            return Array.BinarySearch(skippedSpaces, spaceId) >= 0;
        }

        void AddAdjacentSpace(SpaceBuilder space, int spaceId)
        {
            if (!IsSkippedSpace(spaceId)) 
                space.AdjacentTo(spaceId);
        }
    }
}
